package org.myspringframework.mvc;


import com.xjm.controller.frontend.MainPageController;
import com.xjm.controller.superadmin.HeadLineOperationController;
import com.xjm.enums.HttpMethod;
import lombok.extern.slf4j.Slf4j;
import org.myspringframework.core.BeanContainer;
import org.myspringframework.core.aop.AspectWeaver;
import org.myspringframework.core.inject.DependencyInjector;
import org.myspringframework.mvc.processor.RequestProcessor;
import org.myspringframework.mvc.processor.impl.ControllerRequestProcessor;
import org.myspringframework.mvc.processor.impl.JspRequestProcessor;
import org.myspringframework.mvc.processor.impl.PreRequestProcessor;
import org.myspringframework.mvc.processor.impl.StaticResourceRequestProcessor;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author jaymin<br>
 * 模拟SpringMVC架构编写一个DispatcheServlet<br>
 * <h4>@WebServlet设置为"/",即可拦截几乎所有的请求,不拦截jsp的请求</h4>
 * <h4>切勿设置为"/*",这会让转发到jsp这个请求重新进入"/*"的处理接口，进而无限自循环调用</h4>
 * <h4>详情可以查看tomcat目录的conf/web.xml</h4>
 * <h4>@See: The mappings for the JSP servlet</h4>
 * 2020/11/7 22:13
 */
@Slf4j
@WebServlet("/*")
public class DispatcherServlet extends HttpServlet {
    /**
     * requestProcessor矩阵
     */
    List<RequestProcessor> PROCESSOR = new ArrayList<>();
    @Override
    public void init(){
        // 1. 初始化容器
        BeanContainer beanContainer = BeanContainer.getInstance();
        beanContainer.loadBeans("com.xjm");
        new AspectWeaver().doAop();
        new DependencyInjector().doIoc();
        // 2. 初始化请求处理器责任链
        PROCESSOR.add(new PreRequestProcessor());
        PROCESSOR.add(new StaticResourceRequestProcessor(getServletContext()));
        PROCESSOR.add(new JspRequestProcessor(getServletContext()));
        PROCESSOR.add(new ControllerRequestProcessor());
    }
    /**
     * 统一拦截所有HTTP请求，对路由进行匹配不同的Controller方法 <br>
     * 1. 创建责任链对象实例 <br>
     * 2. 通过责任链模式依次调用请求处理器对请求进行处理 <br>
     * 3. 对处理结果进行渲染 <br>
     *
     * @param request http请求
     * @param response http响应
     */
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response){
        RequestProcessorChain requestProcessorChain = new RequestProcessorChain(PROCESSOR.iterator(), request, response);
        requestProcessorChain.doRequestProcessorChain();
        requestProcessorChain.doRender();
    }
}